var autodb = require('../db/auto.db')
var config = require('../config')
var async = require('async')
var logger = require('../logger')
var emit = require('../emit')


String.prototype.files = function () {
    return this + config.files;
}
String.prototype.tempfiles = function () {
    return this + '.temp' + config.files;
}

function getKeyMatchTags(key, tree) {
    var arr = new Set();
    var keys = key.split('.');
    for (let i in tree) {
        if (keys.length > 1) {
            if (i.search(keys[0]) != -1) {
                for (let j in tree[i]) {
                    if (j.search(keys[1]) != -1){
                        for (let k of tree[i][j]) {
                            if (keys.length > 2){
                                if (k.search(keys[2]) != -1){
                                    arr.add(key.files());
                                }
                            } else {
                                var table = i + '.' + j + '.' + k;
                                arr.add(table.files());
                            }
                        }
                    }
                }
            }
        } else {
            if (i.search(key) != -1) {
                for (let j in tree[i]) {
                    for (let k of tree[i][j]) {
                        var table = i + '.' + j + '.' + k;
                        arr.add(table.files());
                    }
                }
            } else {
                for (let j in tree[i]) {
                    if (j.search(key) != -1) {
                        for (let k of tree[i][j]) {
                            var table = i + '.' + j + '.' + k;
                            arr.add(table.files());
                        }
                    } else {
                        for (let k of tree[i][j]) {
                            if (k.search(key) != -1) {
                                var table = i + '.' + j + '.' + k;
                                arr.add(table.files());
                            }
                        }
                    }
                }
            }
        }
    }
    return arr;
}

function getOrder(order, record) {
    r = 0;
    switch (order) {
        case 'size':
            r = record['size'];
            break;
        case 'near':
            r = record['import'];
            break;
        case 'downloadtimes':
            r = record['downloadtimes'];
            break;
        case 'duration':
            r = record['duration'];
            break;
        case 'name':
            r = 1;
            break;
        default:
            break;
    }
    return r;
}

function queryfileinfo(isMusic, fileid, cb) {
    async.waterfall([
        function (callback) {
            autodb.getfiletags(isMusic, fileid, (err, res) => {
                if (err) {
                    callback(err);
                }
                else {
                    callback(null, res);
                }
            })
        },

        function (tags, callback) {
            if (tags == null) {
                callback(null, null);
            } else {
                autodb.client(isMusic).get(fileid, (err, res) => {
                    if (err) {
                        callback(err);
                    }
                    if (res) {
                        var record = JSON.parse(res);
                        record['tags'] = tags;
                        record['id'] = fileid;
                        callback(null, record);
                    } else {
                        callback(null, null);
                    }
                })
            }
        }
    ], (err, record) => {
        cb(err, record);
    })
}

function buildquerylist(isMusic, key, order, listname, func) {
    async.waterfall([
        //获取所有一级标签
        (callback) => {
            autodb.gettagtree(isMusic, (err, tree) => {
                var keys = key.toLowerCase().split(' ');
                callback(err, tree, keys);
            });
        },

        //构建key.temp.files的临时表
        function (tree, keys, callback) {
            if (keys.length > 0) {
                async.forEach(keys, (key, cb) => {
                    var keytempfiles = key.tempfiles();
                    var tags = getKeyMatchTags(key, tree);
                    if (tags.size > 0) {
                        console.log('sunionstore', keytempfiles, tags);
                        autodb.client(isMusic).sunionstore(keytempfiles, Array.from(tags), (err, response) => {
                            if (err) {
                                cb(err);
                            } else {
                                autodb.client(isMusic).expire(keytempfiles, 2, (err, response) => {
                                    cb(err);
                                });//2秒后自动删除
                            }
                        })
                    }
                    else {
                        cb(null)
                    }
                }, (err) => {
                    callback(err, keys);
                });
            } else {
                callback(null, keys);
            }
        },

        //包装成keys.temp.files
        function (keys, callback) {
            console.log("keys:", keys);
            if (keys.length > 0) {
                var arr = new Array();
                async.forEach(keys, (key, cb) => {
                    if (key.length > 0) {
                        var keytempfiles = key.tempfiles();
                        arr.push(keytempfiles);
                    }
                    cb(null)
                }, (err) => {
                    callback(err, arr)
                })
            } else {
                callback(null, null);
            }
        },

        //求keys对应各个.files的交集
        function (keytempfiles, callback) {
            if (keytempfiles == null || keytempfiles.length < 1) {
                console.log('all.files');
                autodb.client(isMusic).smembers(config.allfile, (err, response) => {
                    callback(err, response);
                })
            }
            else if (keytempfiles.length == 1) {
                console.log('smembers', keytempfiles[0]);
                autodb.client(isMusic).smembers(keytempfiles[0], (err, response) => {
                    callback(err, response);
                })
            } else {
                console.log('sinter', keytempfiles);
                autodb.client(isMusic).sinter(keytempfiles, (err, response) => {
                    callback(err, response);
                })
            }
        },

        //查询最终的列表       
        function (fileids, callback) {
            console.log(fileids)
            var arr = new Array();
            async.forEach(fileids, (fileid, cb) => {
                autodb.getfileinfo(isMusic, fileid, (err, info) => {
                    if (err) {
                        cb();
                    } else {
                        arr.push(info);
                        cb();
                    }
                })
            }, (err) => {
                callback(err, arr);
            });
        },

        //把查询结果放到listname.start.end.ordered临时表
        function (results, callback) {
            var sortedset = listname + '.sorted';
            async.forEach(results, (r, cb) => {
                var o = getOrder(order, r);
                console.log('zadd', sortedset, o, r['id']);
                autodb.client(isMusic).zadd(sortedset, o, r['id'], (err, response) => {
                    console.log('zadd', sortedset, err, response);
                    cb(err, response);
                });
            }, (err) => {
                callback(err, sortedset);
            })
        },

        (sortedset, callback) => {
            autodb.client(isMusic).zrange(sortedset, 0, -1, (err, response) => {
                if (err) {
                    callback(err);
                } else {
                    async.forEach(response, (r, cb) => {
                        autodb.client(isMusic).lpush(listname, r, (err, response) => {
                            cb(err);
                        })
                    }, (err) => {
                        callback(err, sortedset);
                    });
                }
            })
        },

        (sortedset, callback) => {
            autodb.client(isMusic).expire(sortedset, 5, (err, response) => {
                callback(err);
            });
        },

	(callback) => {
            autodb.client(isMusic).zcard('all.names', (err, response) => {
                callback(err, response);
            });
        },

        (numbers , callback) => {
            autodb.client(isMusic).zadd('all.names' , numbers, listname, (err, response) => {
                callback(err);
            });
        },

        (callback) => {
            autodb.client(isMusic).llen(listname, (err, response) => {
                callback(err, response);
            });
        }
    ], (err, len) => {
        func(err, len);
    })
}

function onsocket(socket, data) {
    if(data.key == null){
        console.log('search key is null');
        return;
    }
    var listname = data.key.replace(' ', '_') + '.' + data.order;
    console.log(listname);
    async.waterfall([
        //查listname
        function (callback) {
            if (data.refresh) {
                autodb.client(data.isMusic).del(listname, (err, response) => {
                    callback(err, 0);
                })
            } else {
                autodb.client(data.isMusic).llen(listname, (err, response) => {
                    callback(err, response);
                })
            }
        },
        //构建查询表
        function (size, callback) {
            console.log('size:', size);
            if (size == 0) {
                buildquerylist(data.isMusic, data.key, data.order, listname, (err, len) => {
                    callback(err, len);
                });
            }
            else {
                callback(null, size);
            }
        },

        //到查询表里面分页查询
        function (size, callback) {
            if (size > 0) {
                var min = data.index;
                var max = data.index + data.count - 1;
                autodb.client(data.isMusic).lrange(listname, min, max, (err, response) => {
                    console.log('lrange:', listname, min, max, response);
                    callback(err, size, response);
                })
            } else {
                callback(null, 0, null);
            }
        },

        //给结果集加上tag&info
        function (size, response, callback) {
            if (size == 0) {
                callback(null, 0, null);
            } else {
                var results = new Array();
                async.forEach(response, (r, cb) => {
                    queryfileinfo(data.isMusic, r, function (err, record) {
                        if (record != null) {
                            results.push(record);
                        }
                        cb(err);
                    })
                }, (err) => {
                    if (err) {
                        callback(err);
                    }
                    else {
                        callback(null, size, results);
                    }
                })
            }
        }
    ], (err, len, results) => {
        if (err) {
            console.log(err);
        } else {
            var index = data.index;
            if(len == 0){
                index = 0;
            }
            var param = { index: index, size: len, results: results };
            if (config.debug) {
                console.log(param);
            } else {
                var protocol = data.isMusic ? 'search-music' : 'search-sound';
                emit.send(socket, protocol, param);
            }
        }
    })
}

module.exports = {
    onsocket,
}
